package com.rockcent.api.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.rockcent.api.Routes;
import com.rockcent.common.common.JsonResult;
import com.rockcent.common.common.RestDoing;
import com.rockcent.common.controller.BaseController;
import com.rockcent.helper.LoginFactoryHelper;
import com.rockcent.mall.lib.domain.*;
import com.rockcent.mall.lib.domain.enumclass.SystemType;
import com.rockcent.mall.lib.domain.enumclass.UserInfoStatus;
import com.rockcent.mall.lib.dto.MenuTreeDTO;
import com.rockcent.mall.lib.dto.UserInfoDto;
import com.rockcent.mall.lib.helper.AuthUserHelper;
import com.rockcent.mall.lib.repository.*;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * Created by hone on 17-3-7.
 */
@RestController
@RequestMapping(value = Routes.API_VERSION)
public class SSOController extends BaseController {

    private final Logger log = LoggerFactory.getLogger(SSOController.class);

    @Autowired
    private UserInfoRepository userInfoRepository;
    @Autowired
    private AuthUserHelper userHelper;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private LoginFactoryHelper loginFactoryHelper;

    /**
     * @api {post} /sso/user/login 用户登录接口
     * @apiGroup SSO-USER
     * @apiVersion 1.0.0
     *
     * @apiHeader {String} content-type <code>必须参数</code> 请求content-type
     *
     * @apiParam {String} username <code>必须参数</code> 用户名
     * @apiParam {String} password <code>必须参数</code> 密码
     * @apiParam {String} systemType <code>必须参数</code>类型 必须为 ADMIN("R端"), MALL("M端"), MERCHANT("B端"), SITE("官网")
     *
     * @apiSuccess {Long} id 用户ID
     * @apiSuccess {String} username 用户名称
     * @apiSuccess {String} userToken 用户token
     * @apiSuccess {List} permissionList M与B权限列表
     * @apiSuccess {List} setCookieCustomerDomainList 需要设置cookie的域名
     *
     * @apiSuccess {String} isSuper 是否是超级管理员 YES:是 NO:否 R端
     * @apiSuccess {List} resourceList 资源列表 R端
     *
     * @apiSuccessExample {json} Success-Response:
     * {
     *  "code": "1",
     *  "desc": "成功",
     *  "data": {
     *      "id": 545,
     *      "username": "13450286811",
     *
     *      "permissionList": [
     *           {
     *               "mallName": "测试公司",
     *               "mallLogoPath": null,
     *               "merchantUrl": "http://beta.b.dev.rockcent.com/business",
     *               "mallUrl": "http://beta.b.dev.rockcent.com/mall"
     *           }
     *      ],
     *      "userToken": "07835bbfa03d2133348ff5a996a1cc2e",
     *      "isSuper": "NO",
     *      "resourceList": [
     *           {
     *               "pid": 59,
     *               "id": 61,
     *               "url": "/admin/member_capital"
     *           }
     *      ],
     *      "setCookieCustomerDomainList": [
     *          "test.com",
     *          "sifangstreet.com"
     *      ]
     *  }
     * }
     * @apiErrorExample {json} 101
     * {
     *  "code":"101",
     *  "desc":"用户名不存在"
     * }
     * @apiErrorExample {json} 102
     * {
     *  "code":"102",
     *  "desc":"用户状态异常"
     * }
     * @apiErrorExample {json} 103
     * {
     *  "code":"103",
     *  "desc":"密码错误"
     * }
     *
     */
    @RequestMapping(value = Routes.SSO_USER_LOGIN, method = RequestMethod.POST)
    public JsonResult userLogin(@RequestBody UserInfoDto userInfoDto, HttpServletRequest request, HttpServletResponse response) {
        RestDoing doing = jsonResult -> {
            if (StringUtils.isBlank(userInfoDto.username)) {
                jsonResult.remind(UserInfo.CHECK_USERNAME_IS_NOT_NULL, log);
                return;
            }
            if (StringUtils.isBlank(userInfoDto.password)) {
                jsonResult.remind(UserInfo.CHECK_PASSWORD_IS_NOT_NULL, log);
                return;
            }
            if (StringUtils.isBlank(userInfoDto.getSystemType())) {
                jsonResult.remind(UserInfo.CHECK_SYSTEM_TYPE_IS_NOT_NULL, log);
                return;
            }
            String systemType=userInfoDto.getSystemType();
            if (!EnumUtils.isValidEnum(SystemType.class, systemType)) {
                jsonResult.remind("systemType 必须为 ADMIN(\"R端\"), MALL(\"M端\"), MERCHANT(\"B端\"), SITE(\"官网\")",log);
                return;
            }
            UserInfo userInfo = userInfoRepository.findByUsername(userInfoDto.username);
            if (userInfo == null) {
                jsonResult.custom(JsonResult.CD_101, UserInfo.REMIND_USERNAME_IS_NOT_EXIST, log);//前端要求自定义CODE,用户不存在
                return;
            }
            // 邮箱注册没有激活
            if (UserInfoStatus.INACTIVE.equals(userInfo.getStatus())) {
                jsonResult.custom(JsonResult.CD_102, UserInfo.REMIND_STATUS_EXCEPTION, log);//前端要求自定义CODE 用户未激活
                return;
            }
            if (!UserInfoStatus.ACTIVE.equals(userInfo.getStatus())) {
                jsonResult.custom(JsonResult.CD_102, UserInfo.REMIND_STATUS_EXCEPTION, log);//前端要求自定义CODE 用户已停用或已删除
                return;
            }
            String md5Password = userHelper.getMd5Password(userInfo.getSalt(), userInfoDto.password);
            if (!md5Password.equals(userInfo.getPassword())) {
                jsonResult.custom(JsonResult.CD_103, UserInfo.REMIND_PASSWORD_ERROR, log);//前端要求自定义CODE 密码错误
                return;
            }

            //R端登录 B、M、官网登录
            UserInfoDto result = loginFactoryHelper.createAuthService(systemType).login(userInfo,request);
            if(result!=null) {
                //显示错误信息
                List<String> msgs = result.getErrorMessage();
                if(msgs!=null && msgs.size()>0){
                    jsonResult.remind(msgs.get(0),log);
                    return;
                }
            }
            jsonResult.data = result;
        };

        return doing.go(userInfoDto, null, request, objectMapper, log);
    }

    /**
     * @api {post} /sso/user/token 登录 userToken and domain
     * @apiGroup SSO-USER
     * @apiVersion 1.0.0
     * @apiParam {String} userToken <code>必须参数</code>用户token
     * @apiParam {String} domain <code>必须参数</code>请求域名
     * @apiParam {String} systemType <code>必须参数</code>类型 必须为 ADMIN("R端"), MALL("M端"), MERCHANT("B端"), SITE("官网")
     * @apiParam {Long} merchantId 如果systemType为MERCHANT("B端"),这个参数必填
     *
     * @apiSuccess {String} isSuper 是否是超级管理员 YES:是 NO:否 R端
     * @apiSuccess {List} resourceList 资源列表 M端
     *
     * @apiSuccessExample {json} Success-Response:
     * {
     *  "code": "1",
     *  "desc": "成功",
     *      "data": {
     *          "id": 2,
     *          "username": "lihua",
     *          "mall": {
     *              "id": 1,
     *              "name": "B123aab",
     *              "hostname": "b1.b.dev.rockcent.com",
     *          },
     *          "merchant": {
     *              "id": 1,
     *              "name": "B1",
     *              "email": "renzijian2@rockcent.com",
     *              "intro": "OE 好嘿劲",
     *              "mallId": 1
     *          }
     *      }
     * }
     */
    @RequestMapping(value = Routes.SSO_USER_TOKEN, method = RequestMethod.POST)
    public JsonResult loginUserToken(String userToken, String domain, String systemType, Long merchantId, HttpServletRequest request, HttpServletResponse response) {
        RestDoing doing = jsonResult -> {
            response.setContentType("application/json");
            if (StringUtils.isBlank(userToken)) {
                jsonResult.custom("10001", "user_token 不能为空", log);
                return;
            }
            String finalDomain = domain;
            if (StringUtils.isBlank(finalDomain)) {
                jsonResult.custom("10002", "domain 不能为空", log);
                return;
            }
            if (StringUtils.isBlank(systemType)) {
                jsonResult.remind(UserInfo.CHECK_SYSTEM_TYPE_IS_NOT_NULL, log);
                return;
            }
            if (!EnumUtils.isValidEnum(SystemType.class, systemType)) {
                jsonResult.remind("systemType 必须为 ADMIN(\"R端\"), MALL(\"M端\"), MERCHANT(\"B端\"), SITE(\"官网\")",log);
                return;
            }
            String userInfoId = stringRedisTemplate.boundValueOps(UserInfo.REDIS_USER_TOKEN_PREFIX + userToken).get();
            if (StringUtils.isBlank(userInfoId)) {
                jsonResult.custom("10003", "user_token 无效", log);
                return;
            }
            UserInfo userInfo = userInfoRepository.findOne(Long.valueOf(userInfoId));
            if (userInfo == null) {
                jsonResult.custom("10003", "user_token 无效", log);
                return;
            }
            if(SystemType.valueOf(systemType) == SystemType.MERCHANT) {
                if (merchantId==null) {
                    jsonResult.remind("merchantId不能为空", log);
                    return;
                }
            }
            UserAdmin userAdmin=null;
            UserInfoDto infoDto = loginFactoryHelper.createAuthService(systemType).getManager(userInfo.getId(),domain,userToken,merchantId);
            if(infoDto!=null) {
                //显示错误信息
                List<String> msgs = infoDto.getErrorMessage();
                if(msgs!=null && msgs.size()>0){
                    jsonResult.remind(msgs.get(0),log);
                    return;
                }
            }
            if(SystemType.valueOf(systemType) == SystemType.ADMIN) {
                if(infoDto!=null) {
                    userAdmin = infoDto.getUserAdmin();
                }
            }
            List<MenuTreeDTO> menuTreeDTOs = null;
            String isSuper=null;
            UserMall userMall=null;
            UserMerchant userMerchant=null;
            if(SystemType.valueOf(systemType) == SystemType.MALL) {
                if(infoDto!=null) {
                    isSuper = infoDto.getIsSuper();
                    userMall = infoDto.getUserMall();
                    menuTreeDTOs = infoDto.getResourceList();
                }
            }
            if(SystemType.valueOf(systemType) == SystemType.MERCHANT) {
                if(infoDto!=null) {
                    isSuper = infoDto.getIsSuper();
                    userMerchant = infoDto.getUserMerchant();
                    menuTreeDTOs = infoDto.getResourceList();
                }
            }
            if(SystemType.valueOf(systemType) != SystemType.MALL) {
                String mallId = stringRedisTemplate.boundValueOps(UserInfo.REDIS_MALL_LOGIN_PREFIX + userToken + "_" + domain).get();
                if(StringUtils.isNotEmpty(mallId)) {
                    stringRedisTemplate.delete(UserInfo.REDIS_MALL_LOGIN_PREFIX + userToken + "_" + domain);
                }
            }
            if(SystemType.valueOf(systemType) != SystemType.MERCHANT) {
                String mId = stringRedisTemplate.boundValueOps(UserInfo.REDIS_MERCHANT_LOGIN_PREFIX + userToken + "_" + domain).get();
                if(StringUtils.isNotEmpty(mId)) {
                    stringRedisTemplate.delete(UserInfo.REDIS_MERCHANT_LOGIN_PREFIX + userToken + "_" + domain);
                }
            }
            UserInfoDto userInfoDto = userHelper.setSession(userInfo, userAdmin, request, userMall, userMerchant);
            if(menuTreeDTOs!=null && menuTreeDTOs.size()>0) {
                userInfoDto.setResourceList(menuTreeDTOs);
            }
            if(StringUtils.isNotEmpty(isSuper)) {
                userInfoDto.setIsSuper(isSuper);
            }
            jsonResult.data = userInfoDto;
        };
        return doing.go(request, log);
    }
}

